package phasebook.impl;

import java.util.Calendar;
import java.util.Date;

import javax.ejb.Singleton;
import javax.ejb.EJB;
import javax.ejb.Schedule;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import phasebook.impl.entities.FinancialMovement;
import phasebook.impl.entities.User;

import lottery.RemoteLotteryGameService;
import lottery.msgs.LotteryResult;

@Singleton
public class PhasebookResultFetchingService {

	@PersistenceContext(unitName="phasebook")
	EntityManager em;
	
	@EJB @Inject
	RemoteLotteryGameService lotteryService;
	
	@EJB
	private MailSender mailSender;	
	
	private int previousMinute = 0;
	
	@Schedule(minute="*/3", hour="*", persistent=false)
	public void fetchResults() throws Exception {

		Calendar rightNow = Calendar.getInstance();
		int currentMinute = rightNow.get(Calendar.MINUTE);
				
		if(previousMinute > currentMinute || (previousMinute + 3) <= currentMinute){ // https://issues.jboss.org/browse/EJBTHREE-2229
			
			// Retrieve lottery results
			LotteryResult[] lotteryResults = lotteryService.retrieveResults(1); //PHASEBOOK SYSTEM ID = 1
			
			// Update the winners balance
			for(LotteryResult result : lotteryResults){
				
				// Check if the better is a winner
				if(result.getAmountDue() > 0 ){
					
					// Retrieve the winner
					User winner = em.find(User.class, result.getTokenId());
					
					// Create the associated financial movement
					FinancialMovement movement = new FinancialMovement();
					
					movement.setAmount(result.getAmountDue());
					movement.setDescription(result.getLotteryDescription());
					movement.setUser(winner);
					movement.setTimestamp(new Date(System.currentTimeMillis()));
					
					// Update the database with the movement
					try{
						em.persist(movement);
					}catch(Exception e){
						throw new Exception("Error creating a new movement in the database.", e);
					}

					// Update the winner's balance 
					winner.setBalance(winner.getBalance() + result.getAmountDue());
					
					// Update the winner's balance in the database
					try{
						em.persist(winner);
					}catch(Exception e){
						throw new Exception("Error updating user balance in the database.", e);
					}
				}
			}
			
			// Notify lottery participants
			for(LotteryResult result : lotteryResults){

				// Retrieve the winner
				User lotteryParticipant = em.find(User.class, result.getTokenId());
				
				// Prepare and send email to user
				String	greeting = "Dear ";
				if(result.isWinner()){
					greeting = "Congratulations ";
				}
				
				mailSender.postMail(greeting + lotteryParticipant.getName() + ", the result of lottery {"+ result.getLotteryDescription() +"} is " + result.getResult()+ ", and your bet was " + result.getResultBetted() + ".", "[PHASEBOOK] - Lottery result", lotteryParticipant.getEmail());
			}
			
			previousMinute = currentMinute;
		}
	}

}
